<?php
/**
 * Created by PhpStorm.
 * User: zxd
 * Date: 2016/11/18 0018
 * Time: 下午 8:15
 */

namespace App\Common;


use App\Handler\CompanyHandler;
use App\Models\BaseModel;
use App\Models\CachableModel;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ModelCacher
{

    /**
     * @param $bean CachableModel | BaseModel
     * @param String $db
     */
    static public function resume(&$bean, $db = null)
    {
        $cacheKey = self::getCacheKey($bean, $db);
        $json = Cache::get($cacheKey);
        if (!empty($json)) {
            Log::debug("find $cacheKey from cache ");
            $matrix = json_decode($json, true);
            $bean->forceFill($matrix);
            return;
        }
        $bean->setConnection($db);
        $attributes = $bean->toArray();
        $query = DB::table($bean->getTable())->whereRaw("1=1");
        $columns = $bean->getSolidProperties();
        foreach ($columns as $column) {
            $value = $bean->getAttribute($column);
            if (empty($value)) {
                continue;
            }
            $query->where($column, $value);
        }
        $first = $query->first();
        if (!empty($first)) {
            $bean->forceFill(json_decode(json_encode($first), true));
        } else {
            $bean->setConnection($db)->save();
        }
        self::cache($bean, $db);
    }

    /**
     * @param $bean CachableModel | BaseModel
     * @param String $db
     */
    public static function cache($bean,  $db = null)
    {
        $cacheKey = self::getCacheKey($bean, $db);
        $json = json_encode($bean);
        $expiredAt = $bean->getExpiredAt();
        if (empty($expiredAt)) {
            Cache::forever($cacheKey, $json);
        } else {
            Cache::put($cacheKey, $json, $expiredAt);
        }

    }

    /**
     * @param $bean CachableModel | BaseModel
     * @param string $db
     * @return string
     */
    private static function getCacheKey($bean, $db = null)
    {
        if (empty($db)) {
            $db = "";
        }
        $columns = $bean->getSolidProperties();
        $values = [$db];
        foreach ($columns as $column) {
            array_push($values, $bean->getAttribute($column));
        }
        return implode(":", $values);
    }

    /**
     * @param $bean CachableModel | BaseModel
     * @return string
     */
    public static function replaceIntoDB($bean, $db = null)
    {
        $attributes = $bean->toArray();
        $columns = array_keys($attributes);
        $table = $bean->getTable();
        $columnString = implode(",", $columns);
        $string = "";
        $size = count($columns);
        for ($i = 0; $i < $size; $i++) {
            $string .= ($i == 0) ? "" : ",";
            $string .= "?";
        }
        $sql = "replace into $table ($columnString) values ($string)";
        $values = array_values($attributes);
        DB::connection($db)->insert($sql, $values);
    }
}